/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 teleport_spell.cpp

	$Header: /heroes4/teleport_spell.cpp $

	$NoKeywords: $

 ************************************************************************/
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "teleport_spell.h"

#include "battlefield.h"
#include "battlefield_window.h"
#include "bitmap_group_cache.h"
#include "bound_handler.h"
#include "can_cast.h"
#include "combat_creature.h"
#include "combat_spell_registration.h"
#include "external_string.h"
#include "mouse_window.h"

static t_combat_spell_registration<t_teleport_spell> const
	   k_register_teleport( k_spell_teleport );
static t_bitmap_group_cache const k_teleport_cursor( "cursor.combat.teleport" );

// -----------------------------------------------------------------
// teleport spell handler
// -----------------------------------------------------------------
t_teleport_spell::t_teleport_spell( t_battlefield& battlefield, t_spell spell )
                : t_combat_spell_single_target( battlefield, spell)
{
	m_selecting_source = true;
	m_teleport_cursor.create( k_teleport_cursor.get() );
}

// -----------------------------------------------------------------
// teleport spell handler
// -----------------------------------------------------------------
void t_teleport_spell::cast_and_mirror( t_combat_creature_ptr target, int power )
{
	t_handler handler;
	t_combat_action_message message( *m_caster, get_action_text( false ) );

	m_battlefield.set_spell( this );
	play_sound();
	handler = bound_handler( *this, &t_teleport_spell::move_creature );
	target->fade_out( handler, message );
}

// -----------------------------------------------------------------
// teleport spell handler
// -----------------------------------------------------------------
double t_teleport_spell::ai_weight( t_combat_creature const& target ) const
{
	return 0.0;
}

double t_teleport_spell::get_cancel_weight( t_combat_creature const& target ) const
{
	return 0.0;
}

t_combat_ai_action_list t_teleport_spell::generate_combat_ai_action_list(t_combat_ai &owner)
{
	// Not implemented
	return t_combat_ai_action_list();
}

// -----------------------------------------------------------------
// teleport spell handler
// -----------------------------------------------------------------
static t_external_string const k_text_cannot_fit( "cannot_fit.spells" );
static t_external_string const k_text_move( "teleport.spells" );
static t_external_string const k_text_select_destination( "set_destination.spells" );

t_mouse_window* t_teleport_spell::mouse_move( t_screen_point const& point,
									          std::string& help_text )
{
	if (m_selecting_source)
		return t_combat_spell_single_target::mouse_move( point, help_text );

	t_map_point_2d destination;

	if (!m_battlefield.cell_hit_test( point, destination ))
		return m_battlefield.get_blocked_cursor();

	if (!m_path_finder->get_data( destination ).reachable)
	{
		help_text = replace_spell_keywords( k_text_cannot_fit, *m_caster, m_spell,
			                                  m_spell_target );
		return m_battlefield.get_blocked_cursor();
	}
	help_text = replace_spell_keywords( k_text_move, *m_caster, m_spell, m_spell_target );
	return m_teleport_cursor.cursor;
}

// -----------------------------------------------------------------
// teleport spell handler
// -----------------------------------------------------------------
bool t_teleport_spell::left_click( t_screen_point const& point )
{
	if (m_selecting_source)
	{
		t_combat_creature* creature = m_battlefield.creature_hit_test( point );

		if (creature == 0)
			return false;

		if (!can_cast_on( creature, 0 ))
			return false;

		m_spell_target = creature;
		m_path_finder.reset( new t_combat_path_finder( *creature, false ) );
		m_path_finder->set_teleporting( true );
		m_selecting_source = false;
		m_battlefield.add_prompt( *m_spell_target, k_text_select_destination );
		m_battlefield.get_window()->update_cursor();
		return true;
	}

	t_map_point_2d destination;

	if (!m_battlefield.cell_hit_test( point, destination ))
		return false;

	if (!m_path_finder->get_data( destination ).reachable)
		return false;

	m_destination = m_path_finder->get_data( destination ).nearest_point;
	m_battlefield.begin_spell( m_spell_target );
	return true;
}

// -----------------------------------------------------------------
// teleport spell handler
// -----------------------------------------------------------------
void t_teleport_spell::move_creature()
{
	t_battlefield& battlefield = m_battlefield;
	t_combat_action_message message( *m_caster, get_action_text( false ) );

	m_spell_target->clear_influence();
	if (m_spell_target->is_in_tower())
		m_spell_target->remove_from_tower();
	battlefield.move_object( *m_spell_target,  
	                         m_destination << k_battlefield_subcell_shift );
	if (battlefield.get_tower( m_destination, m_spell_target->get_footprint() ) != 0)
		m_spell_target->place_in_tower();
	m_spell_target->set_influence();
	m_spell_target->fade_in( message );
	battlefield.set_spell( 0 );
}



